/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.mvc.views.platformer
{
	import com.puny.mvc.helpers.FrameHelper;
	import com.puny.mvc.views.View;
	import com.puny.mvc.views.platformer.movieclips.InvisiblePlatformView;
	import com.puny.mvc.views.platformer.movieclips.MainCharacterView;
	import com.puny.mvc.views.platformer.movieclips.PlatformView;
	import com.puny.mvc.views.platformer.movieclips.VerletCharacterView;
	import com.puny.utils.CollisionPt;
//	import com.puny.utils.Curtain;
	import com.puny.utils.ObjectFinder;
	import com.puny.xmlutils.XMLReader;
	
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class MapView extends View {
		protected const GRAVITY:Point = new Point(0,9.8/3);
		private const _objRect:Rectangle = new Rectangle();
		private const _targetRect:Rectangle= new Rectangle();
		private var _map:MovieClip;
		private var _mapName:String;
		private const _platforms:Array = new Array();
		private const _characters:Array = new Array();
		private var _main:MainCharacterView;
		private var _force:Point = new Point();
		private var _stage:DisplayObject;

//		private var _curtain:Curtain;

		
		override public function beforeOpen():void {
//			var shape:Shape = _curtain.fadeIn(1);
//			parent.parent.addChildAt(shape, parent.parent.getChildIndex(parent)+1);
			super.beforeOpen();
			visible = true;
		}
		
//		override public function procedureOpen():Boolean {
//			return _curtain.step();
//		}
		
//		override public function beforeClose():void {
//			var shape:Shape = _curtain.fadeOut();
//			parent.parent.addChildAt(shape, parent.parent.getChildIndex(parent)+1);
//		}
//		
//		override public function procedureClose():Boolean {
//			return _curtain.step();
//		}
		
		override public function afterClose():void {
			_map.removeChild(_main);
			emptyArray(_platforms);
			emptyArray(_characters);
//			_curtain.close();
			removeChild(_map);
			_map = null;
		}


		public function MapView(url:String, name:String) {
			_mapName = name;
			super(url);
		}
		
		public function set timeLineFrame(value:Number):void {
			var f:int = int(value * _map.totalFrames) + 1;
			f = f < 1 ? 1 : (f > _map.totalFrames ? _map.totalFrames : f);
			_map.gotoAndStop(f);
		}
		
		private function generateMap(mapName:String):void {
			_map = getMovieClip(mapName,true,false);
			
		}
		
		public function get mapName():String {
			return _mapName;
		}
		
		override protected function setup():void {
//			_progress = inProgress;
			generateMap(_mapName);
//			var glow:GlowFilter = new GlowFilter(0xFFFFFF,1,20,20,2);
			for(var i:int = 0;i < _map.numChildren;i++) {
				registration( _map.getChildAt(i));
			}
			
		}
		
		override public function beforeReady():void {
			visible = false;
			super.beforeReady();
//			_curtain = new Curtain(Constants.WIDTH,Constants.HEIGHT);
//			FrameHelper.setup(this,null,_curtain.step, _curtain.close);
		}
		
		protected function registration(obj:DisplayObject):void {
			var objName:String = ObjectFinder.eliminateObjectName(obj.toString());

			if (objName == "tw_stage") {
				obj.visible = false;
				_stage = obj;
			}
			if (obj is InvisiblePlatformView || obj is PlatformView ) {
				_platforms.push(obj);
			}
		}
			
		
		public function addBot(bot:DisplayObject):void {
			_map.addChildAt(bot, _map.getChildIndex(_main));
		}
		
		public function removeBot(bot:DisplayObject):void {
			_map.removeChild(bot);
		}
		
		public function set avatar(value:MainCharacterView):void {
			_characters.push(value);
//			addCollisionArea();
			_main = value;
			if (_stage == null) {
				_map.addChild(_main);
			} else {
				_map.addChildAt(_main, _map.getChildIndex(_stage));
			}
			_main.collisionArea = getCollisionArea();
			
		}
		
		public function getCollisionArea():MovieClip {
			var xml:XML = XMLReader.xmlDoc(PlatformerConfigure.CONFIGURE).mainCharacter[0];
			var mc:MovieClip =  getMovieClip(xml.@name);
			mc.alpha = .3;
			return mc;
		}
				
		protected function collision(obj:VerletCharacterView):void {
			var colX:Number;
			var colY:Number;
			var tmp:CollisionPt;
			for each(var platform:PlatformView in _platforms) {
				if (isIgnored(platform)) {
					continue;
				}

				tmp = obj.collision(platform);
				if (tmp != null) {
					hit(obj, platform, tmp);
					if (platform.isActive()) {
						if (tmp.isVertical()) {
							if (isNaN(colX) || tmp.time < colX) {
								colX = tmp.time;
							}
						} else {
							if (isNaN(colY) || tmp.time < colY) {
								colY = tmp.time;
							}
						}
					}
				} else {
					if (platform.isActive() && obj is MainCharacterView) {
						_objRect.x = obj.x+1;
						_objRect.y = obj.y+1;
						_objRect.width = obj.width-1;
						_objRect.height = obj.height-1;
						_targetRect.x = platform.x;
						_targetRect.y = platform.y;
						_targetRect.width = platform.width;
						_targetRect.height = platform.height;
						if (_objRect.intersects(_targetRect)) {
							_force = _force.add(platform.hitPower(obj));
						}
					}
				}
				everyPlatform(obj, platform);
			}
			obj.moveTo(isNaN(colX) ? 1 : colX, isNaN(colY) ? 1 : colY);
			obj.addForce(_force);
			_force.x = 0;
			_force.y = 0;
		}
		
		protected function isIgnored(platfrom:PlatformView):Boolean {return false;}
		protected function hit(obj:VerletCharacterView, platform:PlatformView, tmp:CollisionPt):void {}
		protected function everyPlatform(obj:VerletCharacterView, platform:PlatformView):void {}
		
		protected function get platforms():Array {
			return _platforms;
		}
		
		protected function get map():MovieClip {
			return _map;
		}
		
		protected function get main():MainCharacterView {
			return _main;
		}
		
		protected function get force():Point {
			return _force;
		}
				
		override public function procedureMainFrame():Boolean {
			for each(var character:VerletCharacterView in _characters) {
				character.addForce(GRAVITY);
				character.verlet();
				collision(character);
			}
			return true;
		}
		
		
	}
}